<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模块包装器</title>
        <script type="text/javascript">

            // 定义根模块
            const root = {
                // 用 children 来表示子模块
                children: {
                    // name: module
                }
            }

            // 根据模块名称导入模块
            const require = name => { 
                let module = root.children[ name ];
                if( module ) {
                    return module ;
                }
                throw new Error( `模块${name}不存在` );
            }

            // 模块创建器
            const wrap = (name,wrapper) => {
                // 先尝试从 root 的 子模块中获取 name 对应的模块
                if( root.children[ name ] ){
                    throw new Error(`模块${name}名称已经被占用`);
                }
                // 创建用来实现导出操作的module对象
                let module = {
                    exports: {
                    }
                }
                // 调用 wrapper 函数并为其传入参数
                wrapper( module.exports , require , module );
                // 将通过 module.exports 导出的数据以模块形式添加到 root 模块的 children 中
                root.children[ name ] = module.exports;
            }

            // 定义模块: 调用 wrap 函数并传入两个参数
            // 其中第一个参数表示模块名称
            // 其中第二个参数是个函数，该函数是在 wrap 内部调用并传入参数的
            wrap( 'first' , function(exports,require,module){
                // 通过 module.exports 导出数据
                module.exports = {
                    moduleName: 'first module' ,
                    description : '这是我的第一个模块',
                    version: 1.0 ,
                    show: function(){
                        console.log( this.description );
                    }
                }
            });

            // 定义模块: 调用 wrap 函数并传入两个参数
            wrap( 'second' , function(exports,require,module){
                // 通过 exports 导出数据
                exports.moduleName = 'second module' ;
                exports.description = '这是我的第二个模块';
                exports.version = 2.0 ;
                exports.show = function(){
                    console.log( this.description );
                }
            });

            wrap( 'third' , (exports,require,module)=>{
                const first = require( 'first' );
                const second = require( 'second' );
                console.log( first.moduleName , first.version );
                first.show();

                console.log( second.moduleName , second.version );
                second.show();
            });
           
        </script>
    </head>
    <body>
        <h3>打开浏览器终端查看输出结果</h3>
    </body>
</html>